/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 */
 
#define _GNU_SOURCE
#include "dbsqlite.h"
#include <string.h>
#include <ctype.h>

int check_file_exists(char *path) 
{
	struct stat sts;

	if(stat(path, &sts) == -1 && ENOENT) return 0;
	else return 1;
}

static int
file_select(const struct dirent *entry)
{
	if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) return 0;
	else return 1;
}

void save_state(void)
{
	int db_ret;
	char *err, *sql_st=NULL;

	//save state
	sql_st = sqlite3_mprintf("UPDATE state SET wallpaper='%q', calls='%q', sms='%q', date='%q', time='%q', int_log=%d, int_sms=%d, int_con=%d, no_apps=%d, con_path='%q', cb='%q', show_c=%d, bt_add='%q'", wall_path, app_calls, app_sms, f_date, f_time, int_log, int_sms, int_con, no_apps, con_path, cb_subs, show_c_no, hs_add);
	db_ret = sqlite3_exec(launcher, sql_st, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
	  if (err != NULL) {
		  fprintf(stderr, "1 SQL error: %s\n", err);
		  sqlite3_free(err);
	  }
	}
}

void update_database(void)
{
	char *sql, *err, cat[5][25];
	int db_ret, i;
	
	//alter table
	sql ="ALTER TABLE state ADD COLUMN bt_add text";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "2 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//update version
	sql = "UPDATE state SET version=39, calltime=0";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "3 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}

	//drop table
	sql ="DROP TABLE calls";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "2 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//create table for calls
	sql ="CREATE TABLE calls(key integer primary key, peer text, name text, direction text, duration int, ans iteger, replied integer, new integer, timestamp text, path text)";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "55 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//create table for alarms
	sql ="CREATE TABLE alarms(key integer primary key, time integer, type text, message text)";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "55.2 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//create table for notifications
	sql ="CREATE TABLE notifications(key integer primary key, time integer, message text)";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "55.4 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//alter contacts table
	strcpy(cat[0], "category");
	strcpy(cat[1], "email");
	strcpy(cat[2], "bday");
	strcpy(cat[3], "anniv");
	strcpy(cat[4], "sync");
	
	for (i=0; i<5; i++) {
		if (i<4) sql = sqlite3_mprintf("ALTER TABLE contacts ADD COLUMN %q text",cat[i]);
		else sql = sqlite3_mprintf("ALTER TABLE contacts ADD COLUMN %q integer",cat[i]);
		db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
			  fprintf(stderr, "6 SQL error: %s\n", err);
			  sqlite3_free(err);
			}
		}
		sqlite3_free(sql);
	}
	//add l_type for contacts table
	sql ="ALTER TABLE contacts_addl add column l_type text";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "6.2 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//add l_time for contacts table
	sql ="ALTER TABLE contacts_addl add column l_time text";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "6.2 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//add l_time for contacts table
	sql ="ALTER TABLE contacts_addl add column l_out integer";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "6.2 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//delete home 
	sql ="DELETE FROM category WHERE category = 'Home'";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "2 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
}

void first_run(void)
{
	char *sql, *err, cate[7][255];
	int db_ret, i;
	
	strcpy(f_time, "%H:%M");
	strcpy(f_date, "%d %b %y");
	strcpy(wall_path, "/usr/share/launcher/gradient.png");
	strcpy(app_calls, "/usr/bin/phonelog");
	strcpy(app_sms, "/usr/bin/shr-messages");
	
	//create table state
	sql ="CREATE TABLE state(key integer primary key, version integer, wallpaper text, calls text, sms text, date text, time text, int_log integer, int_sms integer, int_con integer, no_apps integer, location text, calltime text, smstime text, con_path text, cb text, show_c integer, bt_add text)";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "8 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//insert data into state table
	sql = sqlite3_mprintf("INSERT INTO state(version, wallpaper, calls, sms, date, time, int_log, int_sms, int_con, cb, show_c) VALUES(36, '%q', '%q', '%q', '%q', '%q', 1, 1, 1, 'all', 1)", wall_path, app_calls, app_sms, f_date, f_time);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "9 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	sql ="CREATE TABLE apps(key integer primary key, name text, icon text, path text);";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "10 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}	
	sql ="CREATE TABLE app_cat(name text primary key, seq integer, category text);"; //use seq for ordering
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "11 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}	
	sql ="CREATE TABLE category(key integer primary key, seq integer, category text);"; //use seq for ordering
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "12 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//freedesktop standards categories
	strcpy(cate[0], "Audio");
	strcpy(cate[1], "Games");
	strcpy(cate[2], "Graphics");
	strcpy(cate[3], "Home");	
	strcpy(cate[4], "Network");
	strcpy(cate[5], "System");
	strcpy(cate[6], "Utilities");
	for (i =0; i<7; i++) {		
		sql =sqlite3_mprintf("INSERT INTO category(category) VALUES('%q');", cate[i]);
		db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
			  fprintf(stderr, "13 SQL error: %s\n", err);
			  sqlite3_free(err);
			}
		}
	}
	//create table for contacts
	sql ="CREATE TABLE contacts(key integer primary key, name text, path text, phone text, category text, email text, bday text, anniv text, sync integer)"; 
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "54 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}	
	//create table for calls
	sql ="CREATE TABLE calls(key integer primary key, peer text, name text, direction text, duration int, ans iteger, replied integer, new integer, timestamp text, path text)";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "55 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}	
	//create table for sms's
	sql ="CREATE TABLE sms(key integer primary key, timestamp text, sender text, name text, content text, direction text, read integer, sent integer, path text, combined integer)"; 
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "56 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	//create table contacts_cat
	sql ="CREATE TABLE contacts_cat(key integer primary key, category text)";
 	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
 	if (db_ret != SQLITE_OK) {
 		if (err != NULL) {
 			fprintf(stderr, "56.4 SQL error: %s\n", err);
 			sqlite3_free(err);
 		}
 	}
 	//add categories
 	strcpy(cate[0], "Family");
 	strcpy(cate[1], "Friends");
 	strcpy(cate[2], "Work");
 	strcpy(cate[3], "Misc");
 
	for (i=0; i<4; i++) {
		sql = sqlite3_mprintf("INSERT INTO contacts_cat(category) VALUES('%q')", cate[i]);
 		db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
 		if (db_ret != SQLITE_OK) {
 			if (err != NULL) {
 				fprintf(stderr, "56.5 SQL error: %s\n", err);
 				sqlite3_free(err);
 			}
 		}
 		sqlite3_free(sql);
 	}
 	//create contacts_addl table
 	sql ="CREATE TABLE contacts_addl(name text primary key, category text, email text, bday text, anniv text, sync integer, l_type test, l_time text, l_out integer)";
 	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
 	if (db_ret != SQLITE_OK) {
 		if (err != NULL) {
 			fprintf(stderr, "6.5 SQL error: %s\n", err);
 			sqlite3_free(err);
 		}
 	}
}

void restore_state(void)
{
    struct dirent **eps;
	int db_ret, ret, n, version=0, len=0;
	char *sql, db[255], *tok, line[80], *ans, tystr[255];
	const char  *tail;
	sqlite3_stmt *stmt;
	FILE *fp;

	//get the users home directory
	const char *name = "HOME";
	sprintf(launcher_dir, "%s", getenv(name));
	//connect to launcher db
	sprintf(db, "%s/.launcher/launcher.db", launcher_dir);
	db_ret = sqlite3_open(db, &launcher);
	if (db_ret == SQLITE_ERROR || db_ret == SQLITE_CANTOPEN) {
		printf("14 SQL error: %s\n", sqlite3_errmsg(launcher));
		printf("Creating new db file\n");
		ret = system("mkdir ~/.launcher");
		sqlite3_close(launcher);
		db_ret = sqlite3_open(db, &launcher);
		first_run();
	}
	//check for db version
	sql = "SELECT version FROM state";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		if (strcmp(sqlite3_errmsg(launcher), "no such table: state")==0) first_run();
		printf("15 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	db_ret = sqlite3_step(stmt);
	if (db_ret == SQLITE_ROW) version = sqlite3_column_int(stmt, 0);
	sqlite3_finalize(stmt);
	//recreate state table
	printf("db ver:%d\n", version);
	if (version < 39) update_database();
	//restore state
	sql = "SELECT * FROM state";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) printf("16 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	db_ret = sqlite3_step(stmt);
	if (db_ret == SQLITE_ROW) {
		version = sqlite3_column_int(stmt, 1);
		sprintf(wall_path, "%s", sqlite3_column_text(stmt, 2));
		sprintf(app_calls, "%s", sqlite3_column_text(stmt, 3));
		sprintf(app_sms, "%s", sqlite3_column_text(stmt, 4));
		sprintf(f_date, "%s", sqlite3_column_text(stmt, 5));
		sprintf(f_time, "%s", sqlite3_column_text(stmt, 6));
		int_log = sqlite3_column_int(stmt, 7);
		int_sms = sqlite3_column_int(stmt, 8);
		int_con = sqlite3_column_int(stmt, 9);
		no_apps = sqlite3_column_int(stmt, 10);
		if (sqlite3_column_text(stmt, 11)) sprintf(loc, "%s", sqlite3_column_text(stmt, 11));
		if (sqlite3_column_text(stmt, 12)) {
			sprintf(tystr, "%s", sqlite3_column_text(stmt, 12));
			c_ts = atof(tystr);
		}
		if (sqlite3_column_text(stmt, 13)) {
			sprintf(tystr, "%s", sqlite3_column_text(stmt, 13));
			s_ts = atof(tystr);
		}
		if (sqlite3_column_text(stmt, 14)) {
			sprintf(con_path, "%s", sqlite3_column_text(stmt, 14));
		}
		sprintf(cb_subs, "%s", sqlite3_column_text(stmt, 15));
		show_c_no = sqlite3_column_int(stmt, 16);
		if (sqlite3_column_text(stmt, 17)) {
			sprintf(hs_add, "%s", sqlite3_column_text(stmt, 17));
		}
	}
	sqlite3_finalize(stmt);
	strcpy(cur_cat, "Home");
	
	//read no of files from applications dir
	n = scandir ("/usr/share/applications", &eps, file_select, alphasort);
	if (n != no_apps) rescan_apps();

	//set national_prefix, country_code and area_code
	fp = fopen("/etc/phone-utils.conf", "r");
	while ((ans = fgets(line, sizeof line, fp))) {
		if (strncmp(ans, "nat", 3) == 0) {
			tok = strtok(ans, " = ");
			tok = strtok(NULL, " = ");
			strcpy(national_prefix, tok);
			len = strlen(national_prefix);
			for(n=len-1;n>0;n--) if(national_prefix[n] == '\n') {
				national_prefix[n] = '\0'; 
				break;
			}
		}
		if (strncmp(ans, "cou", 3) == 0) {
			tok = strtok(ans, " = ");
			tok = strtok(NULL, " = ");
			strcpy(country_code, tok);
			len = strlen(country_code);
			for(n=len-1;n>0;n--) if(country_code[n] == '\n') {
				country_code[n] = '\0'; 
				break;
			}
		}
		if (strncmp(ans, "are", 3) == 0) {
			tok = strtok(ans, " = ");
			tok = strtok(NULL, " = ");
			strcpy(area_code, tok);
			for(n=len-1;n>0;n--) if(area_code[n] == '\n') {
				area_code[n] = '\0'; 
				break;
			}
		}
	}
	pclose(fp);

	//create the dynamic arrays so we can free them later
	Cat = (_Cat *) malloc(sizeof(_Cat) * 1);
	conv = (_conv *) malloc(sizeof(_conv) * 1);
	Contact = (_contact *) malloc(sizeof(_contact) *1);
	Con_Sms = (_con_sms *) malloc(sizeof(_con_sms) * 1);
}

void get_opimd_data(void)
{
	int db_ret, ret;
	char *sql, *err;
	const char  *tail;
	sqlite3_stmt *stmt;

	//copy pim.db file
	ret = system("cp /etc/freesmartphone/opim/pim.db /home/root/.launcher/");
	
    /*//delete data from contacts table
    sql = "DELETE FROM contacts";
    db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
    if (db_ret != SQLITE_OK) {
                    if (err != NULL) {
                                    fprintf(stderr, "17 SQL error: %s\n", err);
                                    sqlite3_free(err);
                    }
    }*/
    sql = "DELETE FROM sms";
    db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
    if (db_ret != SQLITE_OK) {
                    if (err != NULL) {
                                    fprintf(stderr, "17 SQL error: %s\n", err);
                                    sqlite3_free(err);
                    }
    }
    sql = "DELETE FROM calls";
    db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
    if (db_ret != SQLITE_OK) {
                    if (err != NULL) {
                                    fprintf(stderr, "17 SQL error: %s\n", err);
                                    sqlite3_free(err);
                    }
    }
    //get contacts data and insert into the contacts table
    
}

void rescan_apps(void)
{
    struct dirent **eps=NULL;
	int db_ret, n=0, i=1, c;
	char *sql, app[255], *line, *tystr, tyic[255], typ[255], *err, nm[255], *ok, temp[255];
	const char  *tail;
	sqlite3_stmt *stmt=NULL;
	ssize_t read = 0;
	size_t len = 0;

	printf("scanning apps\n");
	n = scandir ("/usr/share/applications", &eps, file_select, alphasort);
	no_apps = n;
	//empty the app table
	sql ="DELETE FROM apps";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if(db_ret != SQLITE_OK) {
		printf("18 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));		
	}
	//rescan the app table
	if (n > 0) {
		for (i = 0; i < n; i++) {
			len = 0;
			line = (char *) malloc (len+ 1);
			//do not parse directories
			if (eps[i]->d_type == DT_DIR) continue;
			sprintf(app, "/usr/share/applications/%s", eps[i]->d_name);
			fil =  fopen(app, "r");
			while(read != -1) {
				read = getline(&line, &len, fil);
				if (read == -1) break;
				if (strncmp (line, "Exec", 4) == 0) {
					tystr = strtok(line, "=");
					tystr = strtok(NULL, "=");
					strcpy(typ, tystr);
				}
				if (strncmp (line, "Icon", 4) == 0) {
					tystr = strtok(line, "=");
					tystr = strtok(NULL, "=");
					strcpy(tyic, tystr);
				}
				if (strncmp (line, "Name=", 5) == 0) {
					tystr = strtok(line, "=");
					tystr = strtok(NULL, "=");
					strcpy(nm, tystr);
				}
			}
			fclose(fil);
			read = 0;
			//remove /n from their ends
			len = strlen(tyic);
			if(tyic[len-1] == '\n') tyic[len-1] = '\0';
			//add .png to the icon end
			ok = strstr(tyic, ".png");
			if (!ok)  {
				strcat(tyic, ".png");
			}
			//add path to the beginning
			if (tyic[0] != '/') {
				sprintf(temp, "/usr/share/icons/shr/86x86/apps/%s", tyic);
				c = check_file_exists (temp);
				if (!c) sprintf(temp, "/usr/share/pixmaps/%s", tyic);
				strcpy(tyic, temp);
			}
			len = strlen(typ);
			if(typ[len-1] == '\n') typ[len-1] = '\0';			 
			len = strlen(nm);
			if(nm[len-1] == '\n') nm[len-1] = '\0';	
			   
			//put them into apps table
			sql = sqlite3_mprintf("INSERT INTO apps(name, icon, path) VALUES('%q', '%q', '%q');", nm, tyic, typ);
			db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
			if (db_ret != SQLITE_OK) {
				if (err != NULL) {
				  fprintf(stderr, "19 SQL error: %s\n", err);
				  sqlite3_free(err);
				}
			}
			sqlite3_free(sql);

			//put names into app_cat tables if not already there
			sql = sqlite3_mprintf("SELECT COUNT(*) FROM app_cat WHERE name = '%q';", nm);
			db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
			if(db_ret != SQLITE_OK) {
				printf("20 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
			}
			db_ret = sqlite3_step(stmt);
			if (db_ret == SQLITE_ROW) {
				if (sqlite3_column_int(stmt, 0) == 0) { //insert name into app_cat table
					sql = sqlite3_mprintf("INSERT INTO app_cat(name, category) VALUES('%q', 'No Cat');", nm);
					db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
					if (db_ret != SQLITE_OK) {
						if (err != NULL) {
						  fprintf(stderr, "21 SQL error: %s\n", err);
						  sqlite3_free(err);
						}
					}
					sqlite3_free(sql);
				}
			}
			sqlite3_finalize(stmt);
		}
	}
}

void add_hs_items(Evas_Object *win, Evas_Object *bx, Evas_Object *bt, int i)
{
	char *sql, cate[255], *tystr;
	int db_ret;
	const char  *tail;
	sqlite3_stmt *stmt;

	sql = "SELECT category FROM category ORDER BY seq";	
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("22 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(cate, "%s", sqlite3_column_text(stmt, 0));
		bt = elm_button_add(win);
		elm_button_label_set(bt,cate);
		elm_box_pack_end(bx, bt);
		tystr = strdup(cate);
		if (i) evas_object_smart_callback_add(bt, "clicked", select_category, (char *)tystr);
		else evas_object_smart_callback_add(bt, "clicked", set_category, (char *)tystr);
		evas_object_show(bt);
	}
	sqlite3_finalize(stmt);

	if (i) {
		sprintf(cate, "No Cat");
		bt = elm_button_add(win);
		elm_button_label_set(bt,cate);
		elm_box_pack_end(bx, bt);
		tystr = strdup(cate);
		evas_object_smart_callback_add(bt, "clicked", select_category, (char *)tystr);
		evas_object_show(bt);
		
		/*sprintf(cate, "Categorise");
		bt = elm_button_add(win);
		elm_button_label_set(bt,cate);
		elm_box_pack_end(bx, bt);
		tystr = strdup(cate);
		evas_object_smart_callback_add(bt, "clicked", select_category, (char *)tystr);
		evas_object_show(bt);*/
	}
}

int get_apps(char *cat)
{
	int i=0, db_ret, j;
	char *sql;
	const char  *tail;
	sqlite3_stmt *stmt;
	
	sql = sqlite3_mprintf("SELECT apps.icon, apps.path, apps.name FROM apps, app_cat WHERE apps.name = app_cat.name AND app_cat.category = '%q' ORDER BY apps.name", cat);	
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("23 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	if (strcmp(cat, "Home") == 0) {
		//check for in built apps and add if selected
		if (int_con) {
			strcpy(icon[i], "/usr/share/launcher/cont_app.png");
			strcpy(path[i], "int_con");
			strcpy(name[i], "contacts");
			i++;
		}
		if (int_log) {
			strcpy(icon[i], "/usr/share/launcher/log_app.png");
			strcpy(path[i], "int_log");
			strcpy(name[i], "phonelog");
			i++;
		}
		if (int_sms) {
			strcpy(icon[i], "/usr/share/launcher/sms_app.png");
			strcpy(path[i], "int_sms");
			strcpy(name[i], "messaging");
			i++;
		}
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(icon[i], "%s", sqlite3_column_text(stmt, 0));
		sprintf(path[i], "%s", sqlite3_column_text(stmt, 1));
		sprintf(name[i], "%s", sqlite3_column_text(stmt, 2));
		i++;
	}
	for (j = i; j< 200; j++) {
		icon[j][0] = '\0';
		path[j][0]= '\0';
		name[j][0]='\0';
	}
	sqlite3_finalize(stmt);
	return i;
}

void populate_app_list(Evas_Object *list)
{
	int i, db_ret, n_app=0;
	char *sql;
	const char *tail;
	sqlite3_stmt *stmt;
	Elm_Genlist_Item *item;

	sql = "SELECT count(*) FROM app_cat";	
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("24.1 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	if((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		n_app = sqlite3_column_int(stmt, 0);
	}
	sqlite3_finalize(stmt);
	
	free(Cat);
	Cat = (_Cat *) malloc(sizeof(_Cat) * n_app);

	sql = "SELECT name, category from app_cat ORDER BY name";	
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("24.2 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	i = 0;
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(Cat[i].app, "%s", sqlite3_column_text(stmt, 0));
		sprintf(Cat[i].cat, "%s", sqlite3_column_text(stmt, 1));
		elm_genlist_item_append(list, &itc_list, &Cat[i], NULL, 
		                        ELM_GENLIST_ITEM_NONE, NULL, NULL);
		i++;
	}
	sqlite3_finalize(stmt);
	item = elm_genlist_first_item_get(list);
	if (item) elm_genlist_item_selected_set(item, 1);
}

void update_category(char *name, char *cate)
{
	char *sql, *err;
	int db_ret;
	
	sql =sqlite3_mprintf("UPDATE app_cat set category = '%q' WHERE name = '%q';", cate, name);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "25 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void save_wallpaper(void)
{
	char *sql, *err;
	int db_ret;
	
	sql =sqlite3_mprintf("UPDATE state set wallpaper= '%q';", wall_path);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "26 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void populate_cat_list(Evas_Object *lis)
{
	int db_ret;
	char *sql, cate[255], *ca;
	sqlite3_stmt *stmt;
	const char  *tail;

	//get data from categories table and add to cat_list
	sql = "SELECT category FROM category ORDER BY seq";	
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("27 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(cate, "%s", sqlite3_column_text(stmt, 0));
		ca = strdup(cate);
		elm_genlist_item_append(lis, &itc2, (char *)ca, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
	}
	sqlite3_finalize(stmt);
}

void del_category(char * cat)
{
	int db_ret;
	char *err, *sql;
	
	sql = sqlite3_mprintf("DELETE FROM category WHERE category='%q';", cat);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
	  if (err != NULL) {
		  fprintf(stderr, "28 SQL error: %s\n", err);
		  sqlite3_free(err);
	  }
	}
	sqlite3_free(sql);

	sql = sqlite3_mprintf("UPDATE app_cat SET category='No Cat' WHERE category='%q';", cat);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
	  if (err != NULL) {
		  fprintf(stderr, "29 SQL error: %s\n", err);
		  sqlite3_free(err);
	  }
	}
	sqlite3_free(sql);
}

void add_category(char * cat)
{
	int db_ret;
	char *err, *sql;
	
	sql = sqlite3_mprintf("INSERT INTO category(category) VALUES('%q');", cat);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
	  if (err != NULL) {
		  fprintf(stderr, "30 SQL error: %s\n", err);
		  sqlite3_free(err);
	  }
	}
	sqlite3_free(sql);
}

void ren_category(char *old, char *new_nm)
{
	int db_ret;
	char *err, *sql;
	
	sql = sqlite3_mprintf("UPDATE category SET category='%q' WHERE category='%q';", new_nm, old);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
	  if (err != NULL) {
		  fprintf(stderr, "31 SQL error: %s\n", err);
		  sqlite3_free(err);
	  }
	}
	sqlite3_free(sql);

	sql = sqlite3_mprintf("UPDATE app_cat SET category='%q' WHERE category='%q';", new_nm, old);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
	  if (err != NULL) {
		  fprintf(stderr, "32 SQL error: %s\n", err);
		  sqlite3_free(err);
	  }
	}
	sqlite3_free(sql);
}

void add_toolbar_items(void)
{
	char *sql, *tystr, buf[255], cate[255], icon[255];
	int db_ret, ch;
	const char  *tail;
	sqlite3_stmt *stmt;
	Evas_Object *ic;
	
	sql = "SELECT category FROM category ORDER BY seq";	
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("33 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(cate, "%s", sqlite3_column_text(stmt, 0));
		strcpy(icon, cate);
		ch = tolower(cate[0]);
		icon[0] = ch;
		tystr = strdup(cate);
		ic = elm_icon_add(show_apps_win);
		snprintf(buf, sizeof(buf), "/usr/share/launcher/%s.png", icon);
		elm_icon_file_set(ic, buf, NULL);
		if (strcmp(tystr, "System") ==0) tb_item = elm_toolbar_item_add(toolbar, ic, tystr, select_category, (char *) tystr);
		else elm_toolbar_item_add(toolbar, ic, tystr, select_category, (char *) tystr);
	}
	sqlite3_finalize(stmt);

	sprintf(cate, "No Cat");
	tystr = strdup(cate);
	ic = elm_icon_add(show_apps_win);
	snprintf(buf, sizeof(buf), "/usr/share/launcher/uncat.png");
	elm_icon_file_set(ic, buf, NULL);
	elm_toolbar_item_add(toolbar, ic, cate, select_category, (char *) tystr);
	
	sprintf(cate, "Category");
	tystr = strdup(cate);
	ic = elm_icon_add(show_apps_win);
	snprintf(buf, sizeof(buf), "/usr/share/launcher/edit_cat.png");
	elm_icon_file_set(ic, buf, NULL);
	elm_toolbar_item_add(toolbar, ic, cate, (void *)cat_launcher, NULL);

	sprintf(cate, "Configure");
	tystr = strdup(cate);
	ic = elm_icon_add(show_apps_win);
	sprintf(buf, "/usr/share/launcher/configure.png");
	elm_icon_file_set(ic, buf, NULL);
	elm_toolbar_item_add(toolbar, ic, cate, (void *)set_button_clicked, NULL);

	elm_toolbar_item_select(tb_item);
}

void add_toolbar_home_items(Evas_Object *q_tb)
{
	int i=0, db_ret, no_lines, rem, center, x, y, cmp=0;
	char *sql, buf[255], ty[255];
	const char  *tail;
	sqlite3_stmt *stmt;
	Evas_Object *bx, *ic, *lab;
	
	sql = "SELECT apps.icon, apps.path, apps.name FROM apps, app_cat WHERE apps.name = app_cat.name AND app_cat.category = 'Home' ORDER BY apps.name";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("23 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	//check for in built apps and add if selected
	if (int_con) {
		strcpy(icon_home[i], "/usr/share/launcher/cont_app.png");
		strcpy(path_home[i], "int_con");
		strcpy(name_home[i], "contacts");
		i++;
	}
	if (int_log) {
		strcpy(icon_home[i], "/usr/share/launcher/log_app.png");
		strcpy(path_home[i], "int_log");
		strcpy(name_home[i], "phonelog");
		i++;
	}
	if (int_sms) {
		strcpy(icon_home[i], "/usr/share/launcher/sms_app.png");
		strcpy(path_home[i], "int_sms");
		strcpy(name_home[i], "messaging");
		i++;
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(icon_home[i], "%s", sqlite3_column_text(stmt, 0));
		sprintf(path_home[i], "%s", sqlite3_column_text(stmt, 1));
		sprintf(name_home[i], "%s", sqlite3_column_text(stmt, 2));
		i++;
	}
        
	//populate the table
	no_lines = i / 4;
	rem = i%4;
	if (rem > 0) no_lines ++;
	for (y=0; y< no_lines; y++) {
		if (i - cmp == 3) center = 1;
		for (x=0; x<4; x++) {
			cmp = x + y*4;
			if (cmp > i-1) break;
			bx = elm_box_add(win);
			evas_object_show(bx);
	
			ic = elm_icon_add(win);
			strcpy(buf, icon_home[cmp]);
			elm_icon_file_set(ic, buf, NULL);
			elm_icon_scale_set(ic, 1, 1);
			evas_object_size_hint_min_set(ic, 80, 80);
			evas_object_show(ic);
			elm_box_pack_end(bx, ic);			

			lab = elm_label_add(win);
			if (strlen(name_home[cmp]) < 9) strcpy(ty, name_home[cmp]);
			else {
				strncpy(ty, name_home[cmp], 6);
				ty[6] = '.';
				ty[7] = '.';
				ty[8] = '\0';
			}	
			elm_label_label_set(lab, ty);
			elm_box_pack_end(bx, lab);
			evas_object_show(lab);
			if (center) elm_table_pack(q_tb, bx , x+1, y+1, 1, 1);
			else elm_table_pack(q_tb, bx , x, y, 1, 1);
			evas_object_smart_callback_add(ic, "clicked", icon_home_clicked, (void *)cmp);
		}
		center = 0;
	}
	
	sqlite3_finalize(stmt);
}

void refresh_app_data(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path)
{
	size_t len = 0;
	ssize_t read = 0;
	int db_ret;
	char *line, *tystr, typ[255], tyic[255], nm[255], *ok, temp[255], *sql, *err;

	printf("%d %s\n", event, path);
	if (event == ECORE_FILE_EVENT_DELETED_FILE) {
		//remove the entry from the db
		sql = sqlite3_mprintf("DELETE FROM apps WHERE path='%q'", path);
		db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
			  fprintf(stderr, "34 SQL error: %s\n", err);
			  sqlite3_free(err);
			}
		}
		sqlite3_free(sql);		
		//re-select cat
	}
	else if (event == ECORE_FILE_EVENT_CREATED_FILE) {
		//rescan event generated too!
		//scan file at path
		len = 0;
		line = (char *) malloc (len+ 1);
		printf("modified\n");
		fil =  fopen(path, "r");
		while(read != -1) {
			read = getline(&line, &len, fil);
			if (read == -1) break;
			if (strncmp (line, "Exec", 4) == 0) {
				tystr = strtok(line, "=");
				tystr = strtok(NULL, "=");
				strcpy(typ, tystr);
			}
			if (strncmp (line, "Icon", 4) == 0) {
				tystr = strtok(line, "=");
				tystr = strtok(NULL, "=");
				strcpy(tyic, tystr);
			}
			if (strncmp (line, "Name=", 5) == 0) {
				tystr = strtok(line, "=");
				tystr = strtok(NULL, "=");
				strcpy(nm, tystr);
			}
		}
		fclose(fil);
		read = 0;
		//remove /n from their ends
		len = strlen(tyic);
		if(tyic[len-1] == '\n') tyic[len-1] = '\0';
		//add .png to the icon end
		ok = strstr(tyic, ".png");
		if (!ok)  {
			strcat(tyic, ".png");
		}
		//add path to the beginning
		if (tyic[0] != '/') {
			sprintf(temp, "/usr/share/pixmaps/%s", tyic);
			strcpy(tyic, temp);
		}
			   
		len = strlen(typ);
		if(typ[len-1] == '\n') typ[len-1] = '\0';			 
		len = strlen(nm);
		if(nm[len-1] == '\n') nm[len-1] = '\0';	
		//put data into apps table
		sql = sqlite3_mprintf("INSERT INTO apps (name, icon, path) VALUES('%q', '%q', '%q')", nm, tyic, typ);
		db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
			  fprintf(stderr, "35 SQL error: %s\n", err);
			  sqlite3_free(err);
			}
		}
		sqlite3_free(sql);
	}
	else if (event == ECORE_FILE_EVENT_MODIFIED) {
		//rescan file at path
		len = 0;
		line = (char *) malloc (len+ 1);
		printf("modified\n");
		fil =  fopen(path, "r");
		while(read != -1) {
			read = getline(&line, &len, fil);
			if (read == -1) break;
			if (strncmp (line, "Exec", 4) == 0) {
				tystr = strtok(line, "=");
				tystr = strtok(NULL, "=");
				strcpy(typ, tystr);
			}
			if (strncmp (line, "Icon", 4) == 0) {
				tystr = strtok(line, "=");
				tystr = strtok(NULL, "=");
				strcpy(tyic, tystr);
			}
			if (strncmp (line, "Name=", 5) == 0) {
				tystr = strtok(line, "=");
				tystr = strtok(NULL, "=");
				strcpy(nm, tystr);
			}
		}
		fclose(fil);
		read = 0;
		//remove /n from their ends
		len = strlen(tyic);
		if(tyic[len-1] == '\n') tyic[len-1] = '\0';
		//add .png to the icon end
		ok = strstr(tyic, ".png");
		if (!ok)  {
			strcat(tyic, ".png");
		}
		//add path to the beginning
		if (tyic[0] != '/') {
			sprintf(temp, "/usr/share/pixmaps/%s", tyic);
			strcpy(tyic, temp);
		}
			   
		len = strlen(typ);
		if(typ[len-1] == '\n') typ[len-1] = '\0';			 
		len = strlen(nm);
		if(nm[len-1] == '\n') nm[len-1] = '\0';	
		//put data into apps table
		sql = sqlite3_mprintf("UPDATE apps set name='%q' , icon='%q', path='%q' WHERE name = '%q';", nm, tyic, typ);
		db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
			  fprintf(stderr, "36SQL error: %s\n", err);
			  sqlite3_free(err);
			}
		}
		sqlite3_free(sql);
	}
}

void populate_seq_list (Evas_Object *li, char *type) //how many columns for what all data?
{
	char *sql, *tystr, data[255];
	int db_ret;
	const char  *tail;
	sqlite3_stmt *stmt;

	elm_genlist_clear(li);
	
	if(strcmp(type, "Category") == 0) sql = "SELECT category FROM category ORDER BY seq";
	else sql = "SELECT * FROM app_cat ORDER BY category, seq";
			
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("37 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(data, "%s", sqlite3_column_text(stmt, 0));
		tystr = strdup(data);
		elm_genlist_item_append(li, &itc_seq_list, tystr, NULL, 
		                        ELM_GENLIST_ITEM_NONE, NULL, NULL);
	}
	sqlite3_finalize(stmt);
}

void change_seq(Evas_Object *li)
{
	char *sql, *d1, *err;
	int db_ret, i=0;
	Elm_Genlist_Item *item;
	
	//begin transaction
	//clear the table
	sql = "DELETE FROM category";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "38 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}

	//get data from the list and insert into the table
	item = (Elm_Genlist_Item *)elm_genlist_first_item_get(li);
	while (item) {
		d1 = (char *)elm_genlist_item_data_get(item);
		//insert into the table
		sql = sqlite3_mprintf("INSERT INTO category (seq, category) VALUES(%d, '%q');", i, d1);
		db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
			  fprintf(stderr, "39 SQL error: %s\n", err);
			  sqlite3_free(err);
			}
		}
		i++;
		item = elm_genlist_item_next_get(item);
	}
	sqlite3_free(sql);
	//complete transaction
}

void get_calls(void)
{
	int db_ret, i = 0, ans;
	char *sql=NULL, *tok, ty[255], dt[40], format[40];
	sqlite3_stmt *stmt;
	const char  *tail;
	struct tm *loctime;

	elm_genlist_clear(log_list);
	//get data from the calls db and add to the list
	if (strcmp(log_type, "Outgoing") == 0) sql = "SELECT peer, name, duration, timestamp, direction, ans, path FROM calls WHERE direction = 'out' ORDER BY timestamp DESC limit 20";
	else if (strcmp(log_type, "Received") == 0) sql = "SELECT peer, name, duration, timestamp, direction, ans, path FROM calls WHERE direction = 'in' AND ans=1 ORDER BY timestamp DESC limit 20";
	else if (strcmp(log_type, "Missed") == 0) sql = "SELECT peer, name, duration, timestamp, direction, ans, path FROM calls WHERE direction = 'in' AND ans=0 ORDER BY timestamp DESC limit 20";
	else if (strcmp(log_type, "All") == 0) sql = "SELECT peer, name, duration, timestamp, direction, ans, path FROM calls ORDER BY timestamp DESC limit 30";

	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("40 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	//send data about icon, no, 	
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(ty, "%s", sqlite3_column_text(stmt, 0));
		if (strchr(ty, ':')) {
			tok = strtok(ty, ":");
			tok = strtok(NULL, ":");
		}
	    else tok = ty;
		if (sqlite3_column_text(stmt, 1)) sprintf(Log[i].name, "%s", sqlite3_column_text(stmt, 1));
		else strcpy(Log[i].name, "");
		sprintf(Log[i].num, "%s", tok);
		//set time
		sprintf(ty, "%s", sqlite3_column_text(stmt, 3));
		time_t p_time = atof(ty);
		loctime = localtime (&p_time);
		sprintf(format, "%s %s", f_date, f_time);
		strftime(dt, 40, format, loctime);
		sprintf(Log[i].timestamp, "%s", dt);
		Log[i].dur = sqlite3_column_int(stmt, 2);
		sprintf(ty, "%s", sqlite3_column_text(stmt, 4));
		ans =  sqlite3_column_int(stmt, 5);
		if (strcmp(log_type, "Received") == 0) Log[i].icon = 1;
		else if (strcmp(log_type, "Outgoing") == 0) Log[i].icon = 2;
		else if (strcmp(log_type, "Missed") == 0) Log[i].icon = 3;
		else if (strcmp(log_type, "All") == 0) {
			if ((strcmp(ty, "in") == 0) && ans == 1) Log[i].icon = 1;
			if (strcmp(ty, "out") == 0) Log[i].icon = 2;
			if ((strcmp(ty, "in") == 0) && ans == 0) Log[i].icon = 3;
		}
		sprintf(Log[i].path, "%s", sqlite3_column_text(stmt, 6));
		elm_genlist_item_append(log_list, &itc_log, &Log[i], NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
		i++;
	}
	sqlite3_finalize(stmt);
}

int insert_sms_data(_sms_data *SMS)
{
  	int db_ret;
	char *err, *sql, *person, dir[5];
	
	sprintf(dir, "%s", SMS->direction);
	if(strcmp(dir, "out") ==0) person = SMS->recipient;
	else person = SMS->sender;
	sql = sqlite3_mprintf("INSERT INTO sms(timestamp, sender, content, direction, read, path, combined, sent) VALUES(%d, '%q', '%q', '%q', %d, '%q', %d, %d)", 
	                      SMS->timestamp, person, SMS->content, SMS->direction, SMS->read, SMS->path, SMS->combined, SMS->sent);
	db_ret = sqlite3_exec(launcher_thread, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "41 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
	return(sqlite3_last_insert_rowid(launcher_thread));
}

int insert_calls_data(_call_data *Call)
{
  	int db_ret;
	char *err, *sql, ty[255];

	sprintf(ty, "%10.7lf", Call->timestamp);
	sql = sqlite3_mprintf("INSERT INTO calls(peer, timestamp, direction, duration, ans, replied, new, path) VALUES('%q', '%q', '%q', %d, %d, %d, %d, '%q')", 
	                      Call->peer, ty, Call->direction, Call->duration, Call->ans, Call->replied, Call->new_call, Call->path);
	db_ret = sqlite3_exec(launcher_thread, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "42 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	sqlite3_free(sql);	
	return(sqlite3_last_insert_rowid(launcher_thread));
}

int insert_contact_data(_contact *con)
{
  	int db_ret;
	char *err, *sql;
	sqlite3_stmt *stmt;
	const char  *tail;
	
	//put names into contacts_addl table if not already there
	sql = sqlite3_mprintf("SELECT COUNT(*) FROM contacts_addl WHERE name = '%q';", con->name);
	db_ret = sqlite3_prepare_v2(launcher_thread, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("42.5 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher_thread));
	}
	db_ret = sqlite3_step(stmt);
	if (db_ret == SQLITE_ROW) {
		if (sqlite3_column_int(stmt, 0) == 0) { //insert name into app_cat table
			sql = sqlite3_mprintf("INSERT INTO contacts_addl(name, category) VALUES('%q', 'No Cat');", con->name);
			db_ret = sqlite3_exec(launcher_thread, sql, NULL, NULL, &err);
			if (db_ret != SQLITE_OK) {
				if (err != NULL) {
				  fprintf(stderr, "42.55 SQL error: %s\n", err);
				  sqlite3_free(err);
				}
			}
			sqlite3_free(sql);
		}
	}
	sqlite3_finalize(stmt);
	
	sql = sqlite3_mprintf("INSERT INTO contacts(name, phone, path) VALUES('%q', '%q', '%q')", con->name, con->phone, con->path);
	db_ret = sqlite3_exec(launcher_thread, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "43 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
	return(sqlite3_last_insert_rowid(launcher_thread));
}

void match_sms_name(char *peer, int key, char *na)
{
	char m_p[255], *mod_peer, ty[255], *sql, *sql_final, name[255], *err;
	int i, len, db_ret;
	sqlite3_stmt *stmt;
	const char *tail;
	
	//handle peer remove +, national prefix, country_code from the beginning
	strcpy(m_p, peer);
	mod_peer = m_p;
	if (strncmp(m_p, "tel:", 4) == 0) for (i=0; i<4; i++) mod_peer ++;
	strcpy(ty, mod_peer);
	if (ty[0] == '+') mod_peer ++;
	strcpy(ty, mod_peer);
	//check for country_code
	len = strlen(country_code);
	if (strncmp(ty, country_code, len) == 0) for (i=0; i<len; i++) mod_peer ++;
	//check for national_prefix
	len = strlen(national_prefix);
	if (strncmp(ty, national_prefix, len) == 0) for (i=0; i<len; i++) mod_peer ++;
	sql= sqlite3_mprintf("SELECT name FROM contacts WHERE phone LIKE '%%%q' OR phone like '%%%q'", peer, mod_peer);
	db_ret= sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret!= SQLITE_OK) {
		printf("44 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	db_ret= sqlite3_step(stmt);
	if (db_ret == SQLITE_ROW) {
		sprintf(name, "%s", sqlite3_column_text(stmt, 0));
		sql_final = sqlite3_mprintf("UPDATE sms SET name='%q' WHERE key=%d", name, key);
		db_ret = sqlite3_exec(launcher, sql_final, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
			  fprintf(stderr, "45 SQL error: %s\n", err);
			  sqlite3_free(err);
			}
		}
		sqlite3_free(sql_final);
	}
	sqlite3_finalize(stmt);
	strcpy(na, name);
}

void match_call_name(char *peer, int key, char *na)
{
	char m_p[255], *mod_peer, ty[255], *sql, *sql_final, name[255], *err;
	int i, len, db_ret;
	sqlite3_stmt *stmt;
	const char *tail;
	
	//handle peer remove +, national prefix, country_code from the beginning
	strcpy(m_p, peer);
	mod_peer = m_p;
	if (strncmp(m_p, "tel:", 4) == 0) for (i=0; i<4; i++) mod_peer ++;
	strcpy(ty, mod_peer);
	if (ty[0] == '+') mod_peer ++;
	strcpy(ty, mod_peer);	
	//check for country_code
	len = strlen(country_code);
	if (strncmp(ty, country_code, len) == 0) for (i=0; i<len; i++) mod_peer ++;
	strcpy(ty, mod_peer);
	//check for national_prefix
	len = strlen(national_prefix);
	if (strncmp(ty, national_prefix, len) == 0) for (i=0; i<len; i++) mod_peer ++;
	strcpy(ty, mod_peer);
	//check for area code
	len = strlen(area_code);
	if (strncmp(ty, area_code, len) == 0) for (i=0; i<len; i++) mod_peer ++;
	sql= sqlite3_mprintf("SELECT name FROM contacts WHERE phone LIKE '%%%q' OR phone like '%%%q'", peer, mod_peer);
	db_ret= sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret!= SQLITE_OK) {
		printf("46 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	db_ret= sqlite3_step(stmt);
	if (db_ret == SQLITE_ROW) {
		sprintf(name, "%s", sqlite3_column_text(stmt, 0));
		//printf("matched %s\n", name);
		sql_final = sqlite3_mprintf("UPDATE calls SET name='%q' WHERE key=%d", name, key);
		db_ret = sqlite3_exec(launcher, sql_final, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
			  fprintf(stderr, "47 SQL error: %s\n", err);
			  sqlite3_free(err);
			}
		}
		sqlite3_free(sql_final);
	}
	sqlite3_finalize(stmt);
	strcpy(na, name);
}

void match_sms_names(void)
{
	int db_ret, db_ret_1, len, i;
	char *sql, *sql_name, *sql_final, *err, peer[255], name[255], m_p[255], *mod_peer, ty[255];
	sqlite3_stmt *stmt, *stmt_1;
	const char *tail, *tail_1;

	//match phone no's from sms to contacts
	sql = "SELECT sender FROM sms GROUP BY sender";
	db_ret = sqlite3_prepare_v2(launcher_thread, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("48 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher_thread));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(peer, "%s", sqlite3_column_text(stmt, 0));
		//handle peer remove +, national prefix, country_code from the beginning
		strcpy(m_p, peer);
		mod_peer = m_p;
		if (strncmp(m_p, "tel:", 4) == 0) for (i=0; i<4; i++) mod_peer ++;
		strcpy(ty, mod_peer);
		if (ty[0] == '+') mod_peer ++;
		strcpy(ty, mod_peer);
		//check for country_code
		len = strlen(country_code);
		if (strncmp(ty, country_code, len) == 0) for (i=0; i<len; i++) mod_peer ++;
		//check for national_prefix
		len = strlen(national_prefix);
		if (strncmp(ty, national_prefix, len) == 0) for (i=0; i<len; i++) mod_peer ++;
		sql_name = sqlite3_mprintf("SELECT name FROM contacts WHERE phone LIKE '%%%q' OR phone like '%%%q'", peer, mod_peer);
		db_ret_1 = sqlite3_prepare_v2(launcher_thread, sql_name, strlen(sql_name), &stmt_1, &tail_1);
		if(db_ret_1 != SQLITE_OK) {
			printf("49 SQL error: %d %s\n", db_ret_1, sqlite3_errmsg(launcher_thread));
		}
		db_ret_1 = sqlite3_step(stmt_1);
		if (db_ret_1 == SQLITE_ROW) {
			sprintf(name, "%s", sqlite3_column_text(stmt_1, 0));
			//printf("matched %s\n", name);
			sql_final = sqlite3_mprintf("UPDATE sms SET name='%q' WHERE sender='%q'", name, peer);
			db_ret = sqlite3_exec(launcher_thread, sql_final, NULL, NULL, &err);
			if (db_ret != SQLITE_OK) {
				if (err != NULL) {
				  fprintf(stderr, "50 SQL error: %s\n", err);
				  sqlite3_free(err);
				}
			}
			sqlite3_free(sql_final);
		}
		sqlite3_finalize(stmt_1);
	}
	sqlite3_finalize(stmt);
}

void match_call_names(void)
{
	int db_ret, db_ret_1, len, i;
	char *sql, *sql_name, *sql_final, *err, peer[255], name[255], m_p[255], *mod_peer, ty[255];
	sqlite3_stmt *stmt, *stmt_1;
	const char *tail, *tail_1;
	
	//match phone no's from calls to contacts
	sql = "SELECT peer FROM calls GROUP BY peer";
	db_ret = sqlite3_prepare_v2(launcher_thread, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("51 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher_thread));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(peer, "%s", sqlite3_column_text(stmt, 0));
		//handle peer remove +, national prefix, country_code from the beginning
		strcpy(m_p, peer);
		mod_peer = m_p;
		if (strncmp(m_p, "tel:", 4) == 0) for (i=0; i<4; i++) mod_peer ++;
		strcpy(ty, mod_peer);
		if (ty[0] == '+') mod_peer ++;
		strcpy(ty, mod_peer);
		//check for country_code
		len = strlen(country_code);
		if (strncmp(ty, country_code, len) == 0) for (i=0; i<len; i++) mod_peer ++;
		//check for national_prefix
		len = strlen(national_prefix);
		if (strncmp(ty, national_prefix, len) == 0) for (i=0; i<len; i++) mod_peer ++;
		sql_name = sqlite3_mprintf("SELECT name FROM contacts WHERE phone LIKE '%%%q' OR phone like '%%%q'", peer, mod_peer);
		db_ret_1 = sqlite3_prepare_v2(launcher_thread, sql_name, strlen(sql_name), &stmt_1, &tail_1);
		if(db_ret_1 != SQLITE_OK) {
			printf("52 SQL error: %d %s\n", db_ret_1, sqlite3_errmsg(launcher_thread));
		}
		db_ret_1 = sqlite3_step(stmt_1);
		if (db_ret_1 == SQLITE_ROW) {
			sprintf(name, "%s", sqlite3_column_text(stmt_1, 0));
			//printf("matched %s\n", name);
			sql_final = sqlite3_mprintf("UPDATE calls SET name='%q' WHERE peer='%q'", name, peer);
			db_ret = sqlite3_exec(launcher_thread, sql_final, NULL, NULL, &err);
			if (db_ret != SQLITE_OK) {
				if (err != NULL) {
				  fprintf(stderr, "53 SQL error: %s\n", err);
				  sqlite3_free(err);
				}
			}
			sqlite3_free(sql_final);
		}
		sqlite3_finalize(stmt_1);
	}
	sqlite3_finalize(stmt);
}

void insert_location(char *mess)
{
	char *sql, *err;
	int db_ret;
	
	sql = sqlite3_mprintf("UPDATE state SET location='%q'", mess);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
	  if (err != NULL) {
		  fprintf(stderr, "57 SQL error: %s\n", err);
		  sqlite3_free(err);
	  }
	}
}

void begin_transaction(void)
{
	sqlite3_exec(launcher, "BEGIN", 0, 0, 0);
}

void commit_transaction(void)
{
	sqlite3_exec(launcher, "COMMIT", 0, 0, 0);
}

void add_sms_conv()
{
	char *sql, ty[255], dt[40], format[40], dir[4];
	int db_ret, i=0, no_conv=0;
	sqlite3_stmt *stmt;
	const char *tail;
	struct tm *loctime;

	sql = "SELECT count(*) from sms group by sender";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("58.1 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) no_conv++;
	sqlite3_finalize(stmt);
	
	//for the dynamic array
	free (conv);
	conv = (_conv *) malloc(sizeof(_conv) * no_conv);
	
	elm_genlist_clear(conv_list);
	sql = "SELECT sender, name, count(*), max(timestamp), direction from sms group by sender order by max(timestamp) desc";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("58.2 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		if (sqlite3_column_text(stmt, 0) != NULL) sprintf(conv[i].sender, "%s", sqlite3_column_text(stmt, 0));

	else conv[i].sender[0] = '\0';
		if (sqlite3_column_text(stmt, 1) != NULL) sprintf(conv[i].name, "%s", sqlite3_column_text(stmt, 1));
		else conv[i].name[0] = '\0';
		conv[i].count = sqlite3_column_int(stmt, 2);
		sprintf(ty, "%s", sqlite3_column_text(stmt, 3));
		time_t p_time = atof(ty);
		loctime = localtime (&p_time);
		sprintf(format, "%s %s", f_date, f_time);
		strftime(dt, 40, format, loctime);
		sprintf(conv[i].timestamp, "%s", dt);
		sprintf(dir, "%s", sqlite3_column_text(stmt, 4));
		if (strcmp(dir, "out") == 0) conv[i].dir = 1;
		else conv[i].dir = 0;
		elm_genlist_item_append(conv_list, &itc_conv, &conv[i], NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);		
		i++;
	}
	sqlite3_finalize(stmt);
}

void resend_sms(_sms_re *bb)
{
	//name and phone num are already in the array
	strcpy(Re.content, bb->content);
	strcpy(Re.path, bb->path);
	Re.stamp = bb->stamp;
	Re.ic = bb->ic;
	Re.from = 2;
	reply_sms((void *)2, NULL, NULL);
}

void add_conv_sms()
{
	char *sql, content[510], time_stamp[40], dt[40], format[40], ty[255], direction[4], buf[255], *tok=NULL, sms_p[255];
	int db_ret, i=0, sent;
	sqlite3_stmt *stmt;
	const char *tail;
	struct tm *loctime;
	Evas_Object *ic, *bb, *av, *bt, *vbox, *hbox;
	
	//get data from selected item
	Elm_Genlist_Item *item = elm_genlist_selected_item_get(conv_list);
	_conv *con = (_conv *)elm_genlist_item_data_get(item);

	//get no of bubbles to be added
	sql = sqlite3_mprintf("SELECT count(key) from sms WHERE sender='%q'", con->sender);
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("59.5 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	db_ret = sqlite3_step(stmt);
	if (db_ret == SQLITE_ROW) {
		bb_count = sqlite3_column_int(stmt, 0);
	}
	else {
		sqlite3_finalize(stmt);
		sqlite3_free(sql);
		printf("Error: Unable to get sms count\n");
		return;
	}
	sqlite3_finalize(stmt);
	sqlite3_free(sql);
	//set up sms_bb
	sms_bb = (_sms_re *) malloc(sizeof(_sms_re) * bb_count);

	//set up _con_sms
	free(Con_Sms);
	Con_Sms = (_con_sms *) malloc(sizeof(_con_sms) * 1);
	strcpy(Con_Sms->name, con->name);
	strcpy(Con_Sms->p_no, con->sender);
	
	//add bubbles to the bx showing date/time, content
	sql = sqlite3_mprintf("SELECT content, timestamp, direction, path, sent from sms where sender='%q' order by timestamp desc", con->sender);
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("59 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(content, "%s", sqlite3_column_text(stmt, 0));
		sprintf(time_stamp, "%s", sqlite3_column_text(stmt, 1));
		sprintf(direction, "%s", sqlite3_column_text(stmt, 2));
		sprintf(sms_p, "%s", sqlite3_column_text(stmt, 3));
		time_t p_time = atof(time_stamp);
		loctime = localtime (&p_time);
		sprintf(format, "%s %s", f_date, f_time);
		strftime(dt, 40, format, loctime);
		sent = sqlite3_column_int(stmt, 4);
		
		//add vbox 
		vbox = elm_box_add(win_sms);
		evas_object_size_hint_weight_set(vbox, 1.0, 1.0);
		evas_object_size_hint_align_set(vbox, -1.0, 0.0);
		elm_box_pack_end(vbox_sms, vbox);
		evas_object_show(vbox);
		
		//add data to bubble
		ic = elm_icon_add(win_sms);
		bb = elm_bubble_add(win_sms);
		if(strcmp(direction, "out") == 0) {
			elm_bubble_corner_set(bb, "top_right");
			if (sent == 1) snprintf(buf, sizeof(buf), "%s/sms_out.png", "/usr/share/launcher");
			else snprintf(buf, sizeof(buf), "%s/sms_err.png", "/usr/share/launcher");
		}
		else snprintf(buf, sizeof(buf), "%s/sms_in.png", "/usr/share/launcher");
		elm_icon_file_set(ic, buf, NULL);
		elm_icon_scale_set(ic, 1, 1);
		evas_object_size_hint_min_set(ic, 45, 45);
		evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
			
		if(strlen(con->name) > 0) strcpy(ty, con->name);
		else strcpy(ty, con->sender);
		elm_bubble_label_set(bb, ty);
		elm_bubble_info_set(bb, dt);
		elm_bubble_icon_set(bb, ic);
		evas_object_show(ic);
		evas_object_size_hint_weight_set(bb, 1.0, 1.0);
		evas_object_size_hint_align_set(bb, -1.0, 0.0);
		
		av = elm_anchorblock_add(win_sms);
		elm_anchorblock_hover_style_set(av, "popout");
		elm_anchorblock_hover_parent_set(av, win_sms);
		tok = elm_entry_utf8_to_markup(content);
		elm_anchorblock_text_set(av, tok);
		evas_object_smart_callback_add(av, "anchor,clicked", my_anchorblock_anchor, av);
		elm_bubble_content_set(bb, av);
		evas_object_show(av);
		
		elm_box_pack_end(vbox, bb);
		evas_object_show(bb);

		//add an hbox
		hbox = elm_box_add(win_sms);
		elm_box_horizontal_set(hbox, 1);
		evas_object_size_hint_weight_set(hbox, 1.0, 0.0);
		evas_object_size_hint_align_set(hbox, 1.0, 0.0);
		elm_box_pack_end(vbox, hbox);
		evas_object_show(hbox);

		//set up sms_bb values
		strcpy(sms_bb[i].content, content);
		strcpy(sms_bb[i].path, sms_p);
		sms_bb[i].stamp = p_time;
		sms_bb[i].ic = ic;
		sms_bb[i].bb = bb;
		sms_bb[i].ret_bt = NULL;
		
		if ((strcmp(direction, "out") == 0) && sent == 0) {
			bt = elm_button_add(win_sms);
			elm_button_label_set(bt, " Retry ");
			evas_object_size_hint_weight_set(bt, 0.0, 0.0);
			evas_object_size_hint_align_set(bt, 1.0, 0.0);
			elm_box_pack_end(hbox, bt);
			evas_object_show(bt);
			sms_bb[i].ret_bt = bt;
			evas_object_smart_callback_add(bt, "clicked", (void *)resend_sms, &sms_bb[i]);
		}

		//add forward button
		bt = elm_button_add(win_sms);
		elm_button_label_set(bt, "Forward");
		evas_object_size_hint_weight_set(bt, 0.0, 0.0);
		evas_object_size_hint_align_set(bt, 1.0, 0.0);
		elm_box_pack_end(hbox, bt);
		evas_object_show(bt);
		//evas_object_smart_callback_add(bt, "clicked", (void *)del_single_sms, &sms_bb[i]);
		sms_bb[i].fwd_bt = bt;
		
		//add delete button
		bt = elm_button_add(win_sms);
		elm_button_label_set(bt, "Delete");
		evas_object_size_hint_weight_set(bt, 0.0, 0.0);
		evas_object_size_hint_align_set(bt, 1.0, 0.0);
		elm_box_pack_end(hbox, bt);
		evas_object_show(bt);
		sms_bb[i].del_bt = bt;
		evas_object_smart_callback_add(bt, "clicked", (void *)del_single_sms, &sms_bb[i]);

		i++;
	}
	sqlite3_finalize(stmt);
	sqlite3_free(sql);
}

void del_conv(_conv *con)
{
	char *sql, *err, path[255];
	int db_ret;
	sqlite3_stmt *stmt;
	const char *tail;
	
	//get message path from the db
	sql = sqlite3_mprintf("SELECT path FROM sms WHERE sender='%q'", con->sender);
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("60 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(path, "%s", sqlite3_column_text(stmt, 0));
		//delete from opim
		del_sms(path);
	}
	sqlite3_finalize(stmt);
	
	//sender is recipient also in my table
	sql = sqlite3_mprintf("DELETE FROM sms WHERE sender='%q'", con->sender);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "61 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
	evas_object_del(win_sms);
}

void del_sms_path(char *pa)
{
	char *sql, *err;
	int db_ret;
	
	sql = sqlite3_mprintf("DELETE FROM sms WHERE path='%q'", pa);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
		  fprintf(stderr, "62 SQL error: %s\n", err);
		  sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void update_calls_timestamp(void)
{
	char *sql, *err, c_ty[255];
	int db_ret;
	sqlite3_stmt *stmt;
	const char *tail;
	
	//get max timestamp for calls
	sql = "SELECT MAX(timestamp) FROM calls";
	db_ret = sqlite3_prepare_v2(launcher_thread, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("63 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher_thread));
	}
	db_ret = sqlite3_step(stmt);
	if (db_ret == SQLITE_ROW) {
		if (sqlite3_column_text(stmt, 0)) sprintf(c_ty, "%s", sqlite3_column_text(stmt, 0));
		else strcpy(c_ty, "0");
		c_ts = atof(c_ty);
	}
	sqlite3_finalize(stmt);

	sql = sqlite3_mprintf("UPDATE state SET calltime = '%q'", c_ty);
	db_ret = sqlite3_exec(launcher_thread, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "65 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void update_sms_timestamp(void)
{
	char *sql, *err, s_ty[255];
	int db_ret;
	sqlite3_stmt *stmt;
	const char *tail;

	//get max timestamp for sms
	sql = "SELECT MAX(timestamp) FROM sms";
	db_ret = sqlite3_prepare_v2(launcher_thread, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("64 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher_thread));
	}
	db_ret = sqlite3_step(stmt);
	if (db_ret == SQLITE_ROW) {
		if (sqlite3_column_text(stmt, 0)) sprintf(s_ty, "%s", sqlite3_column_text(stmt, 0));
		else strcpy(s_ty, "0");
		s_ts = atof(s_ty);
	}
	sqlite3_finalize(stmt); 

	sql = sqlite3_mprintf("UPDATE state SET smstime = '%q'", s_ty);
	db_ret = sqlite3_exec(launcher_thread, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "65 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void populate_contact_list()
{
	int i, db_ret, no_contacts;
	char *sql;
	const char  *tail;
	sqlite3_stmt *stmt;

	sql = "SELECT count(*) FROM contacts";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("66.1 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	if((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) no_contacts = sqlite3_column_int(stmt, 0);
	else {
		popup_message("Unable to get data from contacts table!", NULL, 1);
		sqlite3_finalize(stmt);
		return;
	}
	sqlite3_finalize(stmt);
	// for dynamic array
	free (Contact);
	Contact = (_contact *) malloc(sizeof(_contact) * no_contacts);
	
	elm_genlist_clear(contact_list);
	sql = "SELECT name, phone, path FROM contacts ORDER BY name COLLATE NOCASE";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("66.2 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	i = 0;
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(Contact[i].name, "%s", sqlite3_column_text(stmt, 0));
		sprintf(Contact[i].phone, "%s", sqlite3_column_text(stmt, 1));
		sprintf(Contact[i].path, "%s", sqlite3_column_text(stmt, 2));
		elm_genlist_item_append(contact_list, &itc_contact, &Contact[i], NULL, 
		                        ELM_GENLIST_ITEM_NONE, NULL, NULL);
		i++;
	}
	sqlite3_finalize(stmt);
}

void del_contact_db(char *path)
{
	char *sql, *err;
	int db_ret;
	
	sql = sqlite3_mprintf("DELETE FROM contacts WHERE path='%q'", path);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "67 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
	populate_contact_list();
}

void del_log_entry_db(char *path)
{
	char *sql, *err;
	int db_ret;
	
	sql = sqlite3_mprintf("DELETE FROM calls WHERE path='%q'", path);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "67.5 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
	get_calls();
}

void update_state_time(int tm, char *field)
{
	char *sql, *err;
	int db_ret;
	
	sql = sqlite3_mprintf("UPDATE state SET %q=%d", field, tm);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "68 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void update_contact_db(char *nam, char *phon, char *path)
{
	char *sql, *err;
	int db_ret;
	
	sql = sqlite3_mprintf("UPDATE contacts SET name='%q', phone='%q' WHERE path='%q'", nam, phon, path);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "69 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
	populate_contact_list();
}

void update_call_db(char *nam, char *phon)
{
	char *sql, *err;
	int db_ret;
	
	sql = sqlite3_mprintf("UPDATE calls SET name='%q' WHERE peer='%q'", nam, phon);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "70 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void add_contact_toolbar_items(void)
{
	Evas_Object *ic;
	int db_ret, ch;
	char *sql, cat[255], *tystr, buf[255], icon[255];
	const char *tail;
	sqlite3_stmt *stmt;

	sql = "SELECT category FROM contacts_cat ORDER BY category COLLATE NOCASE";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("71 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(cat, "%s", sqlite3_column_text(stmt, 0));
		strcpy(icon, cat);
		ch = tolower(cat[0]);
		icon[0] = ch;
		ic = elm_icon_add(contact_win);
		sprintf(buf, "%s/%s.png", "/usr/share/launcher", icon);
		elm_icon_file_set(ic, buf, NULL);
		tystr = strdup(cat);
		if (strcmp(cat, "Family") == 0) cat_tb_item = elm_toolbar_item_add(contact_toolbar, ic, tystr, show_cat_contacts, (char *) tystr);
		else elm_toolbar_item_add(contact_toolbar, ic, tystr, show_cat_contacts, (char *) tystr);
	}
	sqlite3_finalize(stmt);

	//add set cat tb item
	strcpy(cat, "No Cat");
	ic = elm_icon_add(contact_win);
	sprintf(buf, "%s/%s.png", "/usr/share/launcher", cat);
	elm_icon_file_set(ic, buf, NULL);
	tystr = strdup(cat);
	elm_toolbar_item_add(contact_toolbar, ic, tystr, show_cat_contacts, (char *) tystr);
	
	//add set cat tb item
	strcpy(cat, "Set Cat");
	ic = elm_icon_add(contact_win);
	sprintf(buf, "%s/%s.png", "/usr/share/launcher", cat);
	elm_icon_file_set(ic, buf, NULL);
	tystr = strdup(cat);
	elm_toolbar_item_add(contact_toolbar, ic, tystr, show_cat_contacts, (char *) tystr);
	
	//add edit cat tb item
	strcpy(cat, "Edit Cat");
	ic = elm_icon_add(contact_win);
	sprintf(buf, "%s/%s.png", "/usr/share/launcher", cat);
	elm_icon_file_set(ic, buf, NULL);
	tystr = strdup(cat);
	elm_toolbar_item_add(contact_toolbar, ic, tystr, show_cat_contacts, (char *) tystr);
}

void get_cat_contacts(char *cat)
{
	int i, db_ret, no_contacts;
	char *sql;
	const char  *tail;
	sqlite3_stmt *stmt;
	Elm_Genlist_Item *item;

	sql = "SELECT count(*) FROM contacts";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("66.1 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	if((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) no_contacts = sqlite3_column_int(stmt, 0);
	else {
		popup_message("Unable to get data from contacts table!", NULL, 1);
		sqlite3_finalize(stmt);
		return;
	}
	sqlite3_finalize(stmt);
	// for dynamic array
	free (Contact);
	Contact = (_contact *) malloc(sizeof(_contact) * no_contacts);
	
	elm_genlist_clear(contact_list);
	elm_index_item_clear(id);
	if(strcmp(cat, "All") == 0) sql = sqlite3_mprintf("SELECT c.name, c.phone, c.path, c_a.l_type, c_a.l_time, c_a.l_out FROM contacts AS c, contacts_addl AS c_a WHERE c.name = c_a.name ORDER BY c.name COLLATE NOCASE");
	else sql = sqlite3_mprintf("SELECT c.name, c.phone, c.path, c_a.l_type, c_a.l_time, c_a.l_out FROM contacts AS c, contacts_addl AS c_a WHERE c.name = c_a.name AND c_a.category='%q' ORDER BY c.name COLLATE NOCASE", cat);
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("72 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	i = 0;
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		char old_id[32];
		
		sprintf(Contact[i].name, "%s", sqlite3_column_text(stmt, 0));
		sprintf(Contact[i].phone, "%s", sqlite3_column_text(stmt, 1));
		sprintf(Contact[i].path, "%s", sqlite3_column_text(stmt, 2));
		if(sqlite3_column_text(stmt, 3)) sprintf(Contact[i].type, "%s", sqlite3_column_text(stmt, 3));
		else strcpy(Contact[i].type, "");
		if(sqlite3_column_text(stmt, 4)) sprintf(Contact[i].time, "%s", sqlite3_column_text(stmt, 4));
		else strcpy(Contact[i].time, "");
		if(sqlite3_column_int(stmt, 5)) Contact[i].out = 1;
		else Contact[i].out = 0;
		item = elm_genlist_item_append(contact_list, &itc_contact, &Contact[i], NULL, 
		                        ELM_GENLIST_ITEM_NONE, NULL, NULL);
		if ((i == 0) || (toupper(old_id[0]) != toupper(Contact[i].name[0]))) {
			old_id[0] = Contact[i].name[0];
			old_id[1] = '\0';
			elm_index_item_append(id, old_id, item);
		}
		i++;
	}
	sqlite3_finalize(stmt);
	sqlite3_free(sql);
}

void add_contact_hs_items(Evas_Object *wi, Evas_Object *bx, Evas_Object *bt)
{
	char *sql, cate[255], *tystr;
	int db_ret;
	const char  *tail;
	sqlite3_stmt *stmt;

	sql = "SELECT category FROM contacts_cat ORDER BY category COLLATE NOCASE";	
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("73 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(cate, "%s", sqlite3_column_text(stmt, 0));
		bt = elm_button_add(wi);
		elm_button_label_set(bt, cate);
		elm_box_pack_end(bx, bt);
		tystr = strdup(cate);
		evas_object_smart_callback_add(bt, "clicked", (void *)set_con_category, (char *)tystr);
		evas_object_show(bt);
	}
	sqlite3_finalize(stmt);
}

void populate_contact_cat_list(Evas_Object *li)
{
	int db_ret, no_contacts, i;
	char *sql;
	sqlite3_stmt *stmt;
	const char *tail;
	Elm_Genlist_Item *item;

	sql = "SELECT count(*) FROM contacts";
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("74.1 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	if((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) no_contacts = sqlite3_column_int(stmt, 0);
	else {
		popup_message("Unable to get data from contacts table!", NULL, 1);
		sqlite3_finalize(stmt);
		return;
	}
	sqlite3_finalize(stmt);
	
	//for the dynamic array
	free (Contact);
	Contact = (_contact *) malloc(sizeof(_contact) * no_contacts);
	elm_index_item_clear(id);
	sql = "SELECT contacts.name, contacts_addl.category FROM contacts, contacts_addl WHERE contacts.name=contacts_addl.name ORDER BY contacts.name COLLATE NOCASE";	
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("74.2 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	i=0;
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		char old_id[32];
		sprintf(Contact[i].name, "%s", sqlite3_column_text(stmt, 0));
		sprintf(Contact[i].cat, "%s", sqlite3_column_text(stmt, 1));
		item = elm_genlist_item_append(li, &itc_con_cat, &Contact[i], NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
		if ((i == 0) || (toupper(old_id[0]) != toupper(Contact[i].name[0]))) {
			old_id[0] = Contact[i].name[0];
			old_id[1] = '\0';
			elm_index_item_append(id, old_id, item);
		}
		i++;
	}
	sqlite3_finalize(stmt);
}

void set_con_category_clicked(void *data, Evas_Object *obj, void *event_info)
{
	Evas_Object *li = (Evas_Object *)data;
	char *sql, *err, nam[255];
	int db_ret;
	const Eina_List *item;
	_contact *con;
	
	while((item = elm_genlist_selected_items_get(li))) {
		con = (_contact *)elm_genlist_item_data_get(item->data);
		if (con) {
			strcpy(nam, con->name);
			sql = sqlite3_mprintf("UPDATE contacts_addl SET category='%q' WHERE name='%q'", con_cat, nam);
			db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
			if (db_ret != SQLITE_OK) {
				if (err != NULL) {
					fprintf(stderr, "75 SQL error: %s\n", err);
					sqlite3_free(err);
				}
			}
			sqlite3_free(sql);
			elm_genlist_item_del(item->data);
		}
	}
}

void sms_sent_db(char *pa)
{
	char *sql, *err;
	int db_ret;
	
	sql = sqlite3_mprintf("UPDATE sms SET sent=1 WHERE path='%q'", pa);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "76 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void sms_failed_db(char *pa)
{
	char *sql, *err;
	int db_ret;
	
	sql = sqlite3_mprintf("UPDATE sms SET sent=0 WHERE path='%q'", pa);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "77 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void clear_opim_db(char *ty)
{
	char *sql=NULL, *err;
	int db_ret;

	begin_transaction();
	if(strcmp(ty, "sms") == 0) sql = "DELETE FROM sms";
	else if(strcmp(ty, "calls") == 0) sql = "DELETE FROM calls";
	else if(strcmp(ty, "contacts") == 0) sql = "DELETE FROM contacts";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "78 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}

	if(strcmp(ty, "contacts") == 0) {
		commit_transaction();
		return;
	}
	else if(strcmp(ty, "sms") == 0) sql = "UPDATE state SET smstime=0";
	else if(strcmp(ty, "calls") == 0) sql = "UPDATE state SET calltime=0";
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "79 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	commit_transaction();
}

int get_contacts_count_db(void)
{
	char *sql;
	int db_ret;
	const char  *tail;
	sqlite3_stmt *stmt;
	int co=0;
	
	sql = "SELECT count(*) FROM contacts";	
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("80 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		co = sqlite3_column_int(stmt, 0);
	}
	sqlite3_finalize(stmt);
	return co;
}

void update_contact_last(char *ty, int ti, int out, char *na)
{
	char *sql, *err;
	int db_ret;	
	
	sql = sqlite3_mprintf("UPDATE contacts_addl SET l_type='%q', l_time=%d, l_out=%d WHERE name='%q'", ty, ti, out, na);
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "81 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
	sqlite3_free(sql);
}

void clear_log_db(void)
{
	char *sql, *err;
	int db_ret;
	
	if(strcmp(log_type, "Received") == 0) {
		sql = "DELETE FROM calls WHERE direction='in' AND ans=1";
	}
	if(strcmp(log_type, "Missed") == 0) {
		sql = "DELETE FROM calls WHERE direction='in' AND ans=0";
	}
	if(strcmp(log_type, "Outgoing") == 0) {
		sql = "DELETE FROM calls WHERE direction='out'";
	}
	
	db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
	if (db_ret != SQLITE_OK) {
		if (err != NULL) {
			fprintf(stderr, "82 SQL error: %s\n", err);
		  	sqlite3_free(err);
		}
	}
}

void set_seq_db(Evas_Object *li, char *ty)
{
	char *sql, *err;
	int db_ret, i=0;
	Elm_Genlist_Item *item;
	
	//get data from list and populate the table
	if(strcmp(ty, "Category") == 0) {
		item = elm_genlist_first_item_get(li);
		while(item) {
			char *cat = (char *)elm_genlist_item_data_get(item);
			sql = sqlite3_mprintf("UPDATE category SET seq=%d WHERE category='%q'", i, cat);
			db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
			if (db_ret != SQLITE_OK) {
				if (err != NULL) {
					fprintf(stderr, "83 SQL error: %s\n", err);
				  	sqlite3_free(err);
				}
			}
			sqlite3_free(sql);
			i++;
			item = elm_genlist_item_next_get(item);
		}
	}
}

//program comes here if alarm goes off
//or a new alarm is set from some other program and it tells launcher to reload
void reload_alarms(int *k)
{
	char *sql, *err, type[255], mess[255], *sql2;
	int db_ret, tim=0, keys[100], i=0, j=0, key=0, t=*k; //arbitary 100 message limit
	const char  *tail;
	sqlite3_stmt *stmt;
	time_t cur_tim;

	time(&cur_tim);

	//check for alarms whose time has passed and take action for 'notify' types
	sql = sqlite3_mprintf("SELECT * FROM alarms WHERE time < %d ORDER BY time", cur_tim);
	printf("%s\n", sql);
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("84 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		key = sqlite3_column_int(stmt, 0);
		tim = sqlite3_column_int(stmt, 1);
		sprintf(type, "%s", sqlite3_column_text(stmt, 2));
		sprintf(mess, "%s", sqlite3_column_text(stmt, 3));
		if(strcmp(mess, "notify") == 0) {
			//add this alarms' message to the notify table with time
			sql2 = sqlite3_mprintf("INSERT INTO notifications(time, message) VALUES(%q, '%q')", tim, mess);
			printf("%s\n", sql2);
			db_ret = sqlite3_exec(launcher, sql2, NULL, NULL, &err);
			if (db_ret != SQLITE_OK) {
				if (err != NULL) {
					fprintf(stderr, "84.2 SQL error: %s\n", err);
				  	sqlite3_free(err);
				}
			}
			sqlite3_free(sql2);
		}
		//add key to keys array for deletion later
		keys[i] = key;
		i ++;
	}
	sqlite3_finalize(stmt);
	sqlite3_free(sql);
	//check and show if there is anything to show in notification table
	sql = "SELECT COUNT(*) FROM notifications";
	printf("%s\n", sql);
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("85 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		j=sqlite3_column_int(stmt, 0);
	}
	sqlite3_finalize(stmt);
	if (j) show_notifications();
	
	//delete all old alarms
	for(j=0; j<i; j++) {
		sql = sqlite3_mprintf("DELETE FROM alarms WHERE key=%q", keys[i]);
		printf("%s\n", sql);
		db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
				fprintf(stderr, "86 SQL error: %s\n", err);
			  	sqlite3_free(err);
			}
		}
		sqlite3_free(sql);	
	}
	
	//if t > 0 add alarm at t to db
	if (t > 0) {
		sql = sqlite3_mprintf("INSERT INTO alarms(time, type, message) VALUES('%q', 'wake', '')", t);
		printf("%s\n", sql);
		db_ret = sqlite3_exec(launcher, sql, NULL, NULL, &err);
		if (db_ret != SQLITE_OK) {
			if (err != NULL) {
				fprintf(stderr, "87 SQL error: %s\n", err);
			  	sqlite3_free(err);
			}
		}
		sqlite3_free(sql);
	}
	
	//check next alarm time from db
	sql = "SELECT time FROM alarms ORDER BY time LIMIT 1";
	printf("%s\n", sql);
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("88 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		tim = sqlite3_column_int(stmt, 0);
	}
	sqlite3_finalize(stmt);
	clear_suspend_timer();
	set_wake_timer(tim);
	printf("wake timer set\n");
}

void add_notifications(Evas_Object *list)
{
	int db_ret;
	char *sql, *ty, mess[255];
	const char *tail;
	sqlite3_stmt *stmt;

	sql = "SELECT time, message FROM notifications ORDER BY time";
	printf("%s\n", sql);
	db_ret = sqlite3_prepare_v2(launcher, sql, strlen(sql), &stmt, &tail);
	if(db_ret != SQLITE_OK) {
		printf("89 SQL error: %d %s\n", db_ret, sqlite3_errmsg(launcher));
	}
	while((db_ret = sqlite3_step(stmt)) == SQLITE_ROW) {
		sprintf(mess, "%s : %s", sqlite3_column_text(stmt, 0), sqlite3_column_text(stmt, 1));
		ty = strdup(mess);
		elm_genlist_item_append(list, &notify_itc, ty, NULL, 
		                        ELM_GENLIST_ITEM_NONE, NULL, NULL);
	}
	sqlite3_finalize(stmt);
}
